package cloud.pangui.core.lock.annotation;

import java.lang.annotation.*;

/**
 * @Auther hepangui
 * @Date 2019/5/8 0008
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface GlobalLock {
	/**
	 * 默认为类名加方法名
	 * 如果表达式的返回值是基本类型，将会用String.valueOf()转为string
	 * 其他，将使用JSONUtils.toString()来转
	 * 使用方法：
	 * 1.直接使用内置变量
	 * 	 #target  target.getClass().getName()
	 * 	 #method  method.getName()
	 * 	 #args   JSONUtils.toString(args)
	 * 2.使用args变量
	 * 	 #args[0]
	 * 	 #args[0].getId() 只能调用无参方法，不支持复杂方法
	 * 3.$标识静态类方法调用
	 * 	 传入的参数必须与实际需要的参数类型一致，否则解析不出来
	 * 	 StringUtils，DateUtils,JsonUtils,MapUtils,不需要写包名
	 * 	 java.lang下的不需要写包名
	 * 	 其他类，必须写全名称
	 * 示例：
	 * 	 $StringUtils.subStr(args[0],args[1])
	 * 	 $System.nonoTime()
	 * 	 $com.niceloo.core.XXXUtils.aaa(target,method,args)
	 * 4.#开头标识示例调用
	 * 	 #target标识调用当前service的方法，其他标识从beanFactory中获取bean调用
	 * 示例：
	 * 	 #target.xxx(args[0]);
	 *   #beanName.xxx(args[0]，args[1]);
	 * 5.直接使用字符串
	 * 综合示例：
	 * prefix + $StringUtils.toString0(args[0]) +#target + #method
	 * +#args + #args[1] +#args[2].getCarId() + $org.nobject.common.net.URLUtils.decode(args[0])
	 * +#target.getIdByName(args[4])+#carService.findBrandIdByName(args[1]) + postfix
	 */
	String key() default "";

	/**
	 * 重新获取锁的间隔时间，默认100ms
	 */
	long interval() default 100L;

	/**
	 * 失效时间，默认10秒
	 */
	long expireTime() default 10*1000L;

	/**
	 * 阻塞时间，超时获取不到锁，抛异常 或走回调方法
	 */
	long timeout() default 5*1000L;

	/**
	 * 条件表达式
	 * 使用方法同上，但是不支持“+”操作
	 * 可以用"!"在最前面，标识否定
	 * 指定的方法必须返回值为boolean
	 */
	String condition() default "";

	/**
	 * 获取锁失败的回调
	 * 表达式使用方式同上，不支持“+”
	 * 指定方法的返回值必须原原方法的返回值一致
	 * 如果不写，则在获取不到锁时默认跑出异常
	 */
	String callback() default "";
}
